package com.elitect.ftptransfer.module.main.ui;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.net.ftp.FTPFile;

import android.app.AlertDialog;
import android.app.Dialog;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewStub;

import com.elitect.ftptransfer.FtpTransferActivity;
import com.elitect.ftptransfer.R;
import com.elitect.ftptransfer.dialog.MessageDialog;
import com.elitect.ftptransfer.module.main.data.FileItem;
import com.elitect.ftptransfer.module.main.handler.FileBrowserHandler;
import com.elitect.ftptransfer.module.main.handler.OnFileActionHandler;
import com.elitect.ftptransfer.module.main.handler.OnLoadFilesHandler;
import com.elitect.ftptransfer.network.NetworkUtils;

public class MainActivity extends FtpTransferActivity
{
    private static final int[] RESOURCE_FILE_SERVER = {
            R.drawable.ic_add_folder_1, R.drawable.ic_folder_1,
            R.drawable.ic_file_1, R.drawable.ic_back, R.drawable.arrow_down,
            R.drawable.ic_server, Color.parseColor("#0000FF") };
    private static final int[] RESOURCE_FILE_CLIENT = {
            R.drawable.ic_add_folder_2, R.drawable.ic_folder_2,
            R.drawable.ic_file_2, R.drawable.ic_back, R.drawable.arrow_up,
            R.drawable.ic_phone, Color.parseColor("#0000FF") };

    private static final int DIALOG_UPLOAD_FILES = 0;
    private static final int DIALOG_DOWNLOAD_FILES = DIALOG_UPLOAD_FILES + 1;
    private static final int DIALOG_ERROR_FOLDER_NAME = DIALOG_DOWNLOAD_FILES + 1;
    private static final int DIALOG_CREATE_NEW_FOLDER_SUCCESSFUL = DIALOG_ERROR_FOLDER_NAME + 1;
    private static final int DIALOG_CREATE_NEW_FOLDER_FAIL = DIALOG_CREATE_NEW_FOLDER_SUCCESSFUL + 1;
    private static final int DIALOG_FOLDER_ALREADY_EXIST = DIALOG_CREATE_NEW_FOLDER_FAIL + 1;
    private static final int DIALOG_ERROR_SDCARD = DIALOG_FOLDER_ALREADY_EXIST + 1;

    private static final String ROOT_PATH_CLIENT = Environment.getExternalStorageDirectory().getPath()
            + "/";
    // private static final String ROOT_PATH_CLIENT = "/";
    private static final String ROOT_PATH_SERVER = "/";

    private FileBrowserHandler mFileBrowserHandlerServer;
    private FileBrowserHandler mFileBrowserHandlerClient;
    private View mProgressBar;

    private boolean mIsLoadingFileServer = false;
    private boolean mIsLoadingFileClient = false;
    private String mMessageUploadFiles;
    private String mMessageDownloadFiles;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mProgressBar = findViewById(R.id.progress_bar);
        mProgressBar.setVisibility(View.VISIBLE);

        mFileBrowserHandlerClient = new FileBrowserHandler(this,
                RESOURCE_FILE_CLIENT,
                (ViewStub) findViewById(R.id.view_stub_client),
                new OnLoadFilesHandler()
                {
                    @Override
                    public void onLoadFiles(String path)
                    {
                        showProgressBar(true);
                        onLoadLocalFiles(path);
                    }
                }, new OnFileActionHandler()
                {
                    @Override
                    public void onFileAction(List<FileItem> fileItems)
                    {
                        showProgressBar(true);
                        NetworkUtils.doFtpUploadFiles(fileItems,
                                mFileBrowserHandlerServer.getCurrentPath());
                    }

                    @Override
                    public void onCreateNewFolder(String folderName)
                    {
                        if (TextUtils.isEmpty(folderName))
                        {
                            showDialog(DIALOG_ERROR_FOLDER_NAME);
                            return;
                        }

                        createNewLocalFolder(
                                mFileBrowserHandlerClient.getCurrentPath(),
                                folderName);
                    }
                });
        if (!Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED))
        {
            showDialog(DIALOG_ERROR_SDCARD);
            mFileBrowserHandlerClient.unavailable();
        }
        else
        {
            mIsLoadingFileClient = true;
            mFileBrowserHandlerClient.start(ROOT_PATH_CLIENT);
        }

        mFileBrowserHandlerServer = new FileBrowserHandler(this,
                RESOURCE_FILE_SERVER,
                (ViewStub) findViewById(R.id.view_stub_server),
                new OnLoadFilesHandler()
                {
                    @Override
                    public void onLoadFiles(String path)
                    {
                        showProgressBar(true);
                        NetworkUtils.doFtpLoadFiles(path);
                    }
                }, new OnFileActionHandler()
                {
                    @Override
                    public void onFileAction(List<FileItem> fileItems)
                    {
                        showProgressBar(true);
                        NetworkUtils.doFtpDownloadFiles(fileItems,
                                mFileBrowserHandlerServer.getCurrentPath(),
                                mFileBrowserHandlerClient.getCurrentPath());
                    }

                    @Override
                    public void onCreateNewFolder(String folderName)
                    {
                        if (TextUtils.isEmpty(folderName))
                        {
                            showDialog(DIALOG_ERROR_FOLDER_NAME);
                            return;
                        }

                        showProgressBar(true);
                        NetworkUtils.doFtpCreateNewFolder(
                                mFileBrowserHandlerServer.getCurrentPath(),
                                folderName);
                    }
                });
        mIsLoadingFileServer = true;
        mFileBrowserHandlerServer.start(ROOT_PATH_SERVER);
    }

    @Override
    protected void onResume()
    {
        super.onResume();

        NetworkUtils.doFtpCheckConnection();
    }

    @Override
    public void onFtpDisconnect()
    {
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                setResult(RESULT_CANCELED);
                finish();
            }
        });
    }

    @Override
    public void onFtpLoadedFiles(String path, FTPFile[] ftpFiles)
    {
        super.onFtpLoadedFiles(path, ftpFiles);

        if (ftpFiles == null)
        {
            showProgressBar(false);
            toastLong(getString(R.string.error_load_this_folder));
            return;
        }

        List<FileItem> fileItems = new ArrayList<FileItem>();
        for (FTPFile ftpFile : ftpFiles)
        {
            if (ftpFile == null || TextUtils.isEmpty(ftpFile.getName()))
            {
                continue;
            }

            FileItem fileItem = new FileItem();
            fileItem.setName(ftpFile.getName());
            fileItem.setFile(ftpFile.isFile());
            fileItem.setSize(ftpFile.getSize());
            fileItem.setDate(ftpFile.getTimestamp().getTimeInMillis());
            fileItem.setFullPath(ftpFile.getLink());

            fileItems.add(fileItem);
        }

        refeshListFileServer(path, fileItems);
    }

    public void onLoadLocalFiles(String path)
    {
        File[] files = new File(path).listFiles();
        if (files == null)
        {
            showProgressBar(false);
            toastLong(getString(R.string.error_load_this_folder));
            return;
        }

        List<FileItem> fileItems = new ArrayList<FileItem>();
        for (File file : files)
        {
            if (file == null || TextUtils.isEmpty(file.getName()))
            {
                continue;
            }

            FileItem fileItem = new FileItem();
            fileItem.setName(file.getName());
            fileItem.setFile(file.isFile());
            fileItem.setSize(file.isFile() ? file.length() : -1);
            fileItem.setDate(file.lastModified());
            fileItem.setFullPath(file.getAbsolutePath());

            fileItems.add(fileItem);
        }

        refeshListFileClient(path, fileItems);
    }

    @Override
    public void onFtpUploaded(final List<String> listSucessUploadFiles,
            final List<String> listFailUploadFiles)
    {
        super.onFtpUploaded(listSucessUploadFiles, listFailUploadFiles);

        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                mMessageUploadFiles = getString(R.string.files_upload_success);
                if (listSucessUploadFiles.isEmpty())
                {
                    mMessageUploadFiles += getString(R.string.no);
                }
                else
                {
                    for (int indexString = 0; indexString < listSucessUploadFiles.size(); indexString++)
                    {
                        mMessageUploadFiles += " "
                                + listSucessUploadFiles.get(indexString)
                                + ((indexString == listSucessUploadFiles.size() - 1) ? "" : ",");
                    }
                }
                mMessageUploadFiles += "\n"
                        + getString(R.string.files_upload_fail);
                if (listFailUploadFiles.isEmpty())
                {
                    mMessageUploadFiles += getString(R.string.no);
                }
                else
                {
                    for (int indexString = 0; indexString < listFailUploadFiles.size(); indexString++)
                    {
                        mMessageUploadFiles += " "
                                + listFailUploadFiles.get(indexString)
                                + ((indexString == listSucessUploadFiles.size() - 1) ? "" : ",");
                    }
                }

                showDialog(DIALOG_UPLOAD_FILES);
                NetworkUtils.doFtpLoadFiles(mFileBrowserHandlerServer.getCurrentPath());
            }
        });
    }

    @Override
    public void onFtpDownloaded(final List<String> listSucessDownloadFiles,
            final List<String> listFailDownloadFiles)
    {
        super.onFtpDownloaded(listSucessDownloadFiles, listFailDownloadFiles);

        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                mMessageDownloadFiles = getString(R.string.files_download_success);
                if (listSucessDownloadFiles.isEmpty())
                {
                    mMessageDownloadFiles += getString(R.string.no);
                }
                else
                {
                    for (int indexString = 0; indexString < listSucessDownloadFiles.size(); indexString++)
                    {
                        mMessageDownloadFiles += " "
                                + listSucessDownloadFiles.get(indexString)
                                + ((indexString == listSucessDownloadFiles.size() - 1) ? "" : ",");
                    }
                }
                mMessageDownloadFiles += "\n"
                        + getString(R.string.files_download_fail);
                if (listFailDownloadFiles.isEmpty())
                {
                    mMessageDownloadFiles += getString(R.string.no);
                }
                else
                {
                    for (int indexString = 0; indexString < listFailDownloadFiles.size(); indexString++)
                    {
                        mMessageDownloadFiles += " "
                                + listFailDownloadFiles.get(indexString)
                                + ((indexString == listSucessDownloadFiles.size() - 1) ? "" : ",");
                    }
                }

                showDialog(DIALOG_DOWNLOAD_FILES);
                onLoadLocalFiles(mFileBrowserHandlerClient.getCurrentPath());
            }
        });
    }

    protected void createNewLocalFolder(String currentPath, String folderName)
    {
        File file = new File(currentPath + folderName);
        boolean isSuccess = file.mkdir();

        if (isSuccess)
        {
            showDialog(DIALOG_CREATE_NEW_FOLDER_SUCCESSFUL);
        }
        else
        {
            showDialog(DIALOG_FOLDER_ALREADY_EXIST);
            return;
        }

        showProgressBar(true);
        onLoadLocalFiles(currentPath);
    }

    @Override
    public void onFtpCreateFolderFail()
    {
        super.onFtpCreateFolderFail();

        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                showProgressBar(false);
                showDialog(DIALOG_CREATE_NEW_FOLDER_FAIL);
            }
        });
    }

    @Override
    public void onFtpCreateFolderSuccessful()
    {
        super.onFtpCreateFolderSuccessful();

        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                showDialog(DIALOG_CREATE_NEW_FOLDER_SUCCESSFUL);
                NetworkUtils.doFtpLoadFiles(mFileBrowserHandlerServer.getCurrentPath());
            }
        });
    }

    @Override
    public void onFtpLoadFilesFail()
    {
        super.onFtpLoadFilesFail();

        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                showProgressBar(false);
            }
        });
    }

    @Override
    public void onFtpUploadFailAll()
    {
        super.onFtpUploadFailAll();
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                showProgressBar(false);
            }
        });
    }

    @Override
    public void onFtpDownloadFailAll()
    {
        super.onFtpDownloadFailAll();
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                showProgressBar(false);
            }
        });
    }

    @Override
    protected Dialog onCreateDialog(int id)
    {
        if (id == DIALOG_ERROR_SDCARD)
        {
            return new AlertDialog.Builder(this).setIcon(
                    android.R.drawable.ic_dialog_alert).setTitle(R.string.error).setPositiveButton(
                    R.string.ok, null).setMessage(
                    R.string.error_sdcard_not_available).create();
        }
        else if (id == DIALOG_FOLDER_ALREADY_EXIST)
        {
            return new AlertDialog.Builder(this).setIcon(
                    android.R.drawable.ic_dialog_alert).setTitle(
                    R.string.new_folder).setPositiveButton(R.string.ok, null).setMessage(
                    R.string.error_folder_already_exist).create();
        }
        else if (id == DIALOG_CREATE_NEW_FOLDER_FAIL)
        {
            return new AlertDialog.Builder(this).setIcon(
                    android.R.drawable.ic_dialog_alert).setTitle(
                    R.string.new_folder).setPositiveButton(R.string.ok, null).setMessage(
                    R.string.error_create_folder_fail).create();
        }
        else if (id == DIALOG_CREATE_NEW_FOLDER_SUCCESSFUL)
        {
            return new AlertDialog.Builder(this).setIcon(
                    android.R.drawable.ic_dialog_info).setTitle(
                    R.string.new_folder).setPositiveButton(R.string.ok, null).setMessage(
                    R.string.error_create_folder_successful).create();
        }
        else if (id == DIALOG_ERROR_FOLDER_NAME)
        {
            return new AlertDialog.Builder(this).setIcon(
                    android.R.drawable.ic_dialog_alert).setTitle(
                    R.string.new_folder).setPositiveButton(R.string.ok, null).setMessage(
                    R.string.error_input_folder).create();
        }
        else if (id == DIALOG_UPLOAD_FILES)
        {
            return new MessageDialog(this, getString(R.string.upload_files));
        }
        else if (id == DIALOG_DOWNLOAD_FILES)
        {
            return new MessageDialog(this, getString(R.string.download_files));
        }
        else
        {
            return super.onCreateDialog(id);
        }
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog)
    {
        if (id == DIALOG_UPLOAD_FILES)
        {
            ((MessageDialog) dialog).updateMessage(mMessageUploadFiles);
        }
        else if (id == DIALOG_DOWNLOAD_FILES)
        {
            ((MessageDialog) dialog).updateMessage(mMessageDownloadFiles);
        }
        else
        {
            super.onPrepareDialog(id, dialog);
        }
    }

    private void refeshListFileClient(String path, List<FileItem> fileItems)
    {
        mFileBrowserHandlerClient.refreshView(path, fileItems);
        mIsLoadingFileClient = false;
        if (!mIsLoadingFileClient && !mIsLoadingFileServer)
        {
            showProgressBar(false);
        }
    }

    private void refeshListFileServer(final String path,
            final List<FileItem> fileItems)
    {
        runOnUiThread(new Runnable()
        {
            @Override
            public void run()
            {
                mFileBrowserHandlerServer.refreshView(path, fileItems);
                mIsLoadingFileServer = false;
                if (!mIsLoadingFileClient && !mIsLoadingFileServer)
                {
                    showProgressBar(false);
                }
            }
        });
    }

    @Override
    protected void onStop()
    {
        super.onStop();

        NetworkUtils.doFtpLogout();
    }

    private void showProgressBar(boolean isShowed)
    {
        mProgressBar.setVisibility(isShowed ? View.VISIBLE : View.GONE);
    }
}
